/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package web.websocket;

import java.io.IOException;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import javax.websocket.OnClose;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.ServerEndpoint;
import controle.Minimax;
import org.primefaces.json.JSONException;
import org.primefaces.json.JSONObject;

/**
 *
 * @author Weverton
 */
@ServerEndpoint("/jogows")
public class JogoWSEndpoint {

    private static Set<Session> participantes = Collections.synchronizedSet(new HashSet<Session>());
    private static int[][] jogo;
    private static int vez, pontosA, pontosB;

    public JogoWSEndpoint() {
        jogo = getTabuleiro();
    }

    @OnMessage
    public void onMessageJogo(String message, Session session) throws IOException, JSONException {

        JSONObject acoes = new JSONObject(message);

        int tipo = (int) acoes.get("tipo");
        int cont = (int) acoes.get("cont");
        String id = (String) acoes.get("id");
        int dificuldade = (int) acoes.get("dificuldade");
        acoes.put("idJogador", session.getId());

        int i = Integer.parseInt(id.substring(0, 2));
        int j = Integer.parseInt(id.substring(2, 4));
        if (cont % 2 == 1) {
            vez = 2;
        } else {
            vez = 3;
        }
        if (jogo[i][j] == 1) {
            jogo[i][j] = vez;
            // Linha horizontal
            if (i % 2 == 0) {
                if (i > 0) {
                    calcularMeio((i - 1), j);
                }
                if (i < 12) {
                    calcularMeio((i + 1), j);
                }
            } // Linha vertical
            else if (j % 2 == 0) {
                if (j > 0) {
                    calcularMeio(i, (j - 1));
                }
                if (j < 12) {
                    calcularMeio(i, (j + 1));
                }
            }
        }

        if (tipo == 1) {
            if (jogarOutraVez(vez)) {
                cont++;
                acoes.put("cont", cont);
                acoes.put("jogo", jogo);
                for (Session peer : participantes) {
                    peer.getBasicRemote().sendText(acoes.toString());
                }
            } else {
                Minimax jogar = new Minimax();
                cont++;
                do {
                    jogo = jogar.minimax(jogo, dificuldade);
                    acoes.put("cont", cont);
                    acoes.put("jogo", jogo);
                    for (Session peer : participantes) {
                        peer.getBasicRemote().sendText(acoes.toString());
                    }
                } while (jogarOutraVez(vez + 1));
            }
        } else {
            if (jogarOutraVez(vez)) {
                cont++;
            }

            acoes.put("cont", cont);
            acoes.put("jogo", jogo);

            for (Session peer : participantes) {
                peer.getBasicRemote().sendText(acoes.toString());
            }
        }
    }

    @OnOpen
    public void onOpen(Session peer) {
        participantes.add(peer);
    }

    @OnClose
    public void onClose(Session peer) {
        participantes.remove(peer);
    }

    private void calcularMeio(int i, int j) {
        if (jogo[i][j] != 7) {
            jogo[i][j] += 1;
        } else if (vez == 2) {
            jogo[i][j] = 8;
        } else {
            jogo[i][j] = 9;
        }
    }

    private int[][] getTabuleiro() {
        int[][] jogoInicio
                = {{0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0},
                {1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1},
                {0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0},
                {1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1},
                {0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0},
                {1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1},
                {0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0},
                {1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1},
                {0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0},
                {1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1},
                {0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0},
                {1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1},
                {0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0}};
        return jogoInicio;
    }

    private boolean jogarOutraVez(int jog) {
        int val;
        if (jog == 2) {
            val = 8;
        } else {
            val = 9;
        }
        int pontosAtual = 0;
        for (int i = 0; i <= 12; i++) {
            for (int j = 0; j <= 12; j++) {
                if (jogo[i][j] == val) {
                    pontosAtual++;
                }
            }
        }
        if (jog == 2) {
            if (pontosAtual > pontosA) {
                pontosA = pontosAtual;
                return true;
            } else {
                return false;
            }
        } else {
            if (pontosAtual > pontosB) {
                pontosB = pontosAtual;
                return true;
            } else {
                return false;
            }
        }
    }
}
